package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"golang.org/x/crypto/pkcs12"
	"io/ioutil"
	"math/big"
	"os"
	"time"
)

func main() {
	caFile, err := ioutil.ReadFile("ca/ca.crt")
	if err != nil {
		return
	}
	caBlock, _ := pem.Decode(caFile)

	cert, err := x509.ParseCertificate(caBlock.Bytes)
	if err != nil {
		return
	}
	//解析私钥
	keyFile, err := ioutil.ReadFile("ca/ca.pem")
	if err != nil {
		return
	}
	keyBlock, _ := pem.Decode(keyFile)
	praKey, err := x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
	if err != nil {
		return
	}

	p12, err := ioutil.ReadFile("ca/ca.p12")
	p12Private,cert,err:=pkcs12.Decode(p12, "zjzhang")
	privateKey, ok := p12Private.(*rsa.PrivateKey)
	if ok {
		privateKey.Validate()
	}

	/*
		cer := &x509.Certificate{
			SerialNumber: big.NewInt(rd.Int63()), //证书序列号
			Subject: pkix.Name{
				Country:            []string{"CN"},
				Organization:       []string{"Easy"},
				OrganizationalUnit: []string{"Easy"},
				Province:           []string{"ShenZhen"},
				CommonName:         equi.Code,
				Locality:           []string{"ShenZhen"},
			},
			NotBefore:             time.Now(),                  //证书有效期开始时间
			NotAfter:              time.Now().AddDate(1, 0, 0), //证书有效期结束时间
			BasicConstraintsValid: true,                        //基本的有效性约束
			IsCA:           false,                                                                  //是否是根证书
			ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, //证书用途(客户端认证，数据加密)
			KeyUsage:       x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment,
			//EmailAddresses: []string{"test@test.com"},
			//IPAddresses:    []net.IP{net.ParseIP("192.168.1.59")},
		}
	*/
	max := new(big.Int).Lsh(big.NewInt(1), 128)   //把 1 左移 128 位，返回给 big.Int
	serialNumber, _ := rand.Int(rand.Reader, max) //返回在 [0, max) 区间均匀随机分布的一个随机值
	template := x509.Certificate{
		SerialNumber: serialNumber, // SerialNumber 是 CA 颁布的唯一序列号，在此使用一个大随机数来代表它
		Subject: pkix.Name{
			Country:            []string{"CN"},
			Organization:       []string{"Easy"},
			OrganizationalUnit: []string{"Easy"},
			Province:           []string{"ShenZhen"},
			CommonName:         "CommonName",
			Locality: 			[]string{"ShenZhen"},
		},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().AddDate(1, 0, 0), //time.Now().Add(365 * 24 *time.Hour),
		BasicConstraintsValid: true,                        //基本的有效性约束
		IsCA:                  false,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, //证书用途(客户端认证，数据加密)
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,               //KeyUsage 与 ExtKeyUsage 用来表明该证书是用来做服务器认证的
		EmailAddresses:        []string{"test@test.com"},
		//ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, // 密钥扩展用途的序列
		//IPAddresses:    []net.IP{net.ParseIP("127.0.0.1")},
	}
	pk, _ := rsa.GenerateKey(rand.Reader, 2048) //生成一对具有指定字位数的RSA密钥

	//CreateCertificate基于模板创建一个新的证书
	//第二个第三个参数相同，则证书是自签名的
	//返回的切片是DER编码的证书

	derBytes, _ := x509.CreateCertificate(rand.Reader, &template, cert, &pk.PublicKey, praKey) //DER 格式
	certOut, _ := os.Create("cert.crt")
	//CERTIFICATE
	_ = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	_ = certOut.Close()


	data := x509.MarshalPKCS1PrivateKey(pk)
	block, err := x509.EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", data, []byte("zjzhang"), x509.PEMCipher3DES)
	file, err := os.Create("zjzhang.pem")
	err = pem.Encode(file, block)
	err =file.Close()



	keyOut, err := os.Create("key.pem")
	//pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)})
	err = pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)})
	err = keyOut.Close()
}
